STM32: 做一个与ST

您所在的位置:网站首页 st-link utility怎么加密 STM32: 做一个与ST

STM32: 做一个与ST

2024-07-12 00:38| 来源: 网络整理| 查看: 265

ST官方提供了ST-LINK/V2-1调试器的原理图,PCB图及相关的固件更新工具(Stlink Utility或者ST-LINK firmware upgrade)当然也可以通过第三方的工具对调试器进行固件的升级操作(STLinkReflash)。但如果你在使用ST-LINK/V2-1的过程中不慎将原有的固件破环或者是MCU烧毁,使得ST-LINK/V2-1无法正常使用,这时候你就需要一个可用的bootloader进行修复。

-实现一个简单的bootloader, 能够实现固件的下载及加载

经过进一个月的分析,不断尝试,自己写一个bootloader实现固件下载更新及加载也是可能的。

完整的固件包含如下这几个部分:

Flash size: 128KiB bootloader: 15KiB system parameter: 1KiB                              firmware: 111KiB manifest: 1KiB -了解固件升级相关的通信协议

由于STLinkReflash命令在固件升级过程中,可以显示升级过程中发送及接收的数据的相关内容,并且结合OpenOCD源代码中关于ST-LINK通信相关的代码,可以很容易地猜测出固件升级的流程:

STM32: ST-LINK/V2与STLINK/V2-1 DFU协议分析

NOTE:

STLinkReflash工具在写入ST-LINK/V2-1的时候,没有去更新固件的配置信息(位于flash 0x08003c00 ~ 0x08003ffff)。这使得如果bootloader不包启配置信息(只包含flash前15KiB的数据),那么通过该工具写入的ST-LINK/V2-1固件是无法使用的(USB无法正常枚举),而必须先通过STLink Utility工具进行固件更新。

加密算法,通过分析STLinkReflash工具,我们知道固件在传送过程中,会进行加密,我们需要相关的加密算法来实现:

STM32: 实现Advanced Encryption Standard(AES) – 128-bit加密算法

- 官方原版bootloader

有了固件升级相关的通信协议及相关的参考文档,获取官方的bootloader也不是什么难事。

原以为有了ST-LINK/V2-1的固件并且知道固件的起始地址,就可以写一个简单的bootloader加载固件,可事实并非如此(加载JLink固件可以正常运行,但是对于ST-LINK/V2-1的固件,就没有那么走运了),还是需要分析调试bootloader代码,以发现其中的差异:

STM32: 从STLinkReflash提取jlink与ST-LINK/V2-1固件

 

- USB接口实现及其配置

ST-LINK/V2-1通过USB接口与PC机进行通信,在bootloader模式下接口的相关配置信息在linux/ubuntu下可通过lsusb命令查看:

$ lsusb -d 0483: -v Bus 001 Device 014: ID 0483:3748 STMicroelectronics ST-LINK/V2 Couldn't open device, some information will be missing Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0483 STMicroelectronics idProduct 0x3748 ST-LINK/V2 bcdDevice 1.00 iManufacturer 1 iProduct 2 iSerial 3 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 39 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 3 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 4 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0

有了这些相关信息,我们就可以完成USB接口配置的相关代码了。这里我们会用到EP 1 IN 与 EP 2 OUT而EP 3 IN在ST-LINK进行debug/trace的时候会用到。

-基于ChibiOS/RT v16.1.2的实时系统实现的bootloader

1. 系统上电之后会检查固件是否完整,固件完整则跳转执行固件代码否则进入DFU模式:

/* * Application entry point. */ int __attribute__((noreturn)) main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. */ halInit(); do { uint32_t flashSize, magicValue; /* Check the firmware intergrity */ flashSize = (*(volatile uint32_t *)0x1FFFF7E0 & 0xffff) CSR & RCC_CSR_SFTRSTF) != 0 && BKP->DR1 != 0xfeed) { /* Software reset occurred */ break; } if (BKP->DR1 == 0xfeed) BKP->DR1 = 0x0000; /* Clear reset flag */ RCC->CSR |= RCC_CSR_RMVF; JumpToUserApp(0x08004000); } while (0); /* * System initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ chSysInit(); // ... }

NOTE:

这里可以看到固件检查及跳转是在halInit()之后及chSysInit()之前。

2. 跳转时要重新设置线程工作模式: 在特权模式下运行并使用Main Stack:

void JumpToUserApp(uint32_t pAppAddr) { volatile uint32_t *pMspAddr; volatile uint32_t *pJmpAddr; /* Get main stack address from the application vector table */ pMspAddr = (volatile uint32_t *)(pAppAddr + 0); /* Get jump address from application vector table */ pJmpAddr = (volatile uint32_t *)(pAppAddr + 4); /* Set stack pointer as in application's vector table */ __set_MSP(*pMspAddr); /* Privileged and using main stack */ __set_CONTROL(0); /* Jump to the new application */ (*(void (*)(void))*pJmpAddr)(); }

NOTE:

ChibiOS/RT初始化时,会使MCU工作在特权模式下,但使用的stack为thread stack。相关的代码在:os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s

/** * @brief Control special register initialization value. * @details The system is setup to run in privileged mode using the PSP * stack (dual stack mode). */ #if !defined(CRT0_CONTROL_INIT) || defined(__DOXYGEN__) #define CRT0_CONTROL_INIT (CONTROL_USE_PSP | \ CONTROL_MODE_PRIVILEGED) #endif // ... Reset_Handler: /* Interrupts are globally masked initially.*/ cpsid i /* PSP stack pointers initialization.*/ ldr r0, =__process_stack_end__ msr PSP, r0 #if CRT0_INIT_FPU == TRUE /* FPU FPCCR initialization.*/ movw r0, #CRT0_FPCCR_INIT & 0xFFFF movt r0, #CRT0_FPCCR_INIT >> 16 movw r1, #SCB_FPCCR & 0xFFFF movt r1, #SCB_FPCCR >> 16 str r0, [r1] dsb isb /* CPACR initialization.*/ movw r0, #CRT0_CPACR_INIT & 0xFFFF movt r0, #CRT0_CPACR_INIT >> 16 movw r1, #SCB_CPACR & 0xFFFF movt r1, #SCB_CPACR >> 16 str r0, [r1] dsb isb /* FPU FPSCR initially cleared.*/ mov r0, #0 vmsr FPSCR, r0 /* FPU FPDSCR initially cleared.*/ movw r1, #SCB_FPDSCR & 0xFFFF movt r1, #SCB_FPDSCR >> 16 str r0, [r1] /* Enforcing FPCA bit in the CONTROL register.*/ movs r0, #CRT0_CONTROL_INIT | CONTROL_FPCA #else movs r0, #CRT0_CONTROL_INIT #endif /* CONTROL register initialization as configured.*/ msr CONTROL, r0 isb // ... -相关源代码

这里提供部分代码供参考:

https://github.com/brobwind/chibios_bro_dbg_link_v2_1 -预编译固件及己知问题

相关的固件可以从这里下载:2016_11_24_BRO-DBG-LINK-V2-1_BL-20161121.bin

己知问题:

- 下载ST-LINK/V2-1固件之后,无法再通过Stlink Utility,STLink firmware upgrade和STLinkReflash工具更新固件。

NOTE:

设置volume label可以通过ST-LINK firmware upgrade工具完成,label的最大长度为11字节。

ST-LINK firmware upgrade工具还可以指定固件类型:

2016_11_24_stlink_fw_upgrade_adv

相关的参考文档 http://www.chibios.org/dokuwiki/doku.php http://www.st.com/zh/embedded-software/stsw-link007.html http://infocenter.arm.com/help/topic/com.arm.doc.dai0179b/ar01s02s06.html 相关文档: STM32: 实现Advanced Encryption Standard(AES) – 128-bit加密算法 STM32: 实现AES 128-bit加密算法 - 标准实现 STM32: Black Magic Probe @ BRO-DBG-LINK-V2-1 STM32: BRO-DBG-LINK – 如何让USB设备重新枚举 STM32: 通过ST-LINK/V2-1+OpenOCD更新GD32F150C6T6固件


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3